<template>
  <span
    class="vs_icon"
    :style="boxStyle"
  >
    <i
      v-if="type === 'iconfont'"
      :class="[fontFamily, conf.fontClass]"
      :style="imgStyle"
    ></i>
    <el-image
      v-else-if="type === 'serverImg' && checkExist"
      :src="imgUrl"
      :style="imgStyle"
      @error="imgLoadErr"
    >
      <template #placeholder>
        <div
          class="image-slot"
        >
          <el-icon><Loading /></el-icon>
        </div>
      </template>
    </el-image>
    <img
      v-else-if="type === 'serverImg' && imgUrl_"
      :src="imgUrl_"
      :style="imgStyle"
    />
    <img
      v-else-if="type === 'png'"
      :src="conf.src"
      :style="imgStyle"
    />
  </span>
</template>
<script>
import { getCssStyle, getServerImgUrl, convertImgUrlToBlob, loadCssLink, getVappDir } from '@/utils/util.js';
import { mapState } from 'vuex';
import dfConf from '@/components/common/icon/icon-default.js';
import storage from '@/storage/storage.js';

export default {
  components: {},
  inject: {
    panelWid: {
      default: '',
    },
  },
  props: {
    conf: {
      type: Object,
      default: () => JSON.parse(JSON.stringify(dfConf)),
    },
    resize: {
      type: Boolean,
      default: true,
    },

    // 是否预览图（未跟组件绑定关系的临时图片，url?preview=1）
    preview: {
      type: Boolean,
      default: false,
    },

    checkExist: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['imgLoadErr'],
  data() {
    return {
      dfConf,
      imgUrl_: '',
    };
  },
  computed: {
    ...mapState({
      rate: state => state.VisualComponentsModule.rate,
    }),
    conf_() {
      return {
        ...dfConf,
        ...this.conf,
      };
    },
    type() {
      return this.conf_.type;
    },
    iconId() {
      return this.conf['icon_id'];
    },
    fontFamily() {
      let fontFamily = '';
      const { fontClass } = this.conf_;
      if (fontClass) {
        const arr = ['vs_icon1', 'vs_icon2', 'vs_icon3', 'vs_icon_dev'];
        fontFamily = arr.find(n => fontClass.includes(n)) || '';
      }
      return fontFamily;
    },
    imgUrl() {
      let imgUrl = '';
      if (this.type === 'serverImg') {
        const { icon_id: iconId, apiType, serType } = this.conf_;
        imgUrl = getServerImgUrl(iconId, apiType, this.preview);
        if (serType === 5 || serType === 9) { // 9：新图片库上传的图片
          const splitor = imgUrl.includes('?') ? '&' : '?';
          imgUrl += `${splitor}type=${serType}`;
        }
      }
      return imgUrl;
    },
    boxStyle() {
      if (this.type === 'iconfont') {
        return this.getCssStyle(this.conf_.boxStyle);
      }
      const { sourceIcon_id: sourceIconId } = this.conf_;
      if (sourceIconId.startsWith('00000001-0000-0000-0003')) { // 地图图标
        const style = { ...this.imgStyle, backgroundColor: '#485d74' };
        return style;
      } else {
        return this.imgStyle;
      }
    },
    imgStyle() {
      const { color, fontSize, width, height } = this.conf_.imgStyle;
      let style = {};
      if (this.type === 'iconfont') {
        style = { color, fontSize };
      } else if (this.conf_.sourceIcon_id && this.conf_.sourceIcon_id.includes('tabLine')) {
        style = { width };
      } else {
        style = { width, height };
      }
      return this.getCssStyle(style);
    },
  },
  watch: {
    'conf.icon_id': {
      handler(newIconId, oldIconId) {
        this.initImgUrl();
      },
      immediate: true,
    },
  },
  created() {
    this.loadIconFontCss();
  },
  methods: {
    getCssStyle(style) {
      const s = getCssStyle(style, this.resize);
      if (this.resize) {
        if (style.width) {
          s.width = `${style.width * this.rate}px`;
        }
        if (style.height) {
          s.height = `${style.height * this.rate}px`;
        }
      }
      if (s.backgroundColor) {
        s.backgroundColor = s.backgroundColor.replace(/\s?\!important/, '');
      }
      return s;
    },
    imgLoadErr() {
      this.$emit('imgLoadErr', this.conf);
    },
    async initImgUrl() {
      if (!this.imgUrl) {
        return;
      }

      // 只在预览组件中使用图片缓存
      if (this.panelWid) {
        this.imgUrl_ = this.imgUrl;
        return;
      }

      if (!window.visualComp.imgCaches) {
        window.visualComp.imgCaches = {};
      }
      const { imgCaches } = window.visualComp;
      if (imgCaches[this.iconId]) {
        this.imgUrl_ = imgCaches[this.iconId];
        return;
      }

      let blob = await storage.getItem(`imgBlob_${this.iconId}`, 'tenant', true);
      if (!blob) {
        blob = await convertImgUrlToBlob(this.imgUrl);
        if (!blob) {
          this.imgUrl_ = this.imgUrl;
          return;
        }

        const imgCacheTimout = 24 * 60 * 60 * 1000; // 图片缓存时间
        storage.setItem(`imgBlob_${this.iconId}`, blob, 'tenant', imgCacheTimout);
      }

      const imgUrl_ = URL.createObjectURL(blob);
      imgCaches[this.iconId] = imgUrl_;
      this.imgUrl_ = imgUrl_;
    },

    loadIconFontCss() {
      if (window.visualComp.iconfontLoad) {
        return;
      }
      window.visualComp.iconfontLoad = true;
      const arr = ['vs_icon1', 'vs_icon2', 'vs_icon3'];
      const vappUrl = getVappDir();
      arr.forEach(n => {
        loadCssLink(`${vappUrl}/iconfont/${n}/iconfont.css`);
      });
    },
  },
};
</script>
<style lang="less" scoped>
.vs_icon {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  border: 0px solid transparent;
  overflow: hidden;
  box-sizing: border-box;
  i,
  img {
    max-width: 100%;
    max-height: 100%;
  }
  i {
    display: inline-block;
    line-height: 1;
  }
  > img {
  }
  .image-slot {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
</style>
